/*
 *      Author: Guannan Ma
 *      @mythmgn
 *      Whatever license applied
 *      @brief
 *          I ported some codes from PJD program.
 *          Hat off to the author "Pawel Jakub Dawidek <pjd@FreeBSD.org> "
 */

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "base.h"


BOOL
isContainSign(char *line) {
    //ASSERT(line);
    int pos,i;
    pos=-1;
    for (i=0; i<strlen(line); i++) {
        if (line[i]==' '||line[i]=='\t')
            continue;
        else if (line[i]!='#'&&line[i]!='\n'&&line[i]!='\0')
            return FALSE;
        else
            break;
    }
    return TRUE;
}

EXBOOL
readLine(FILEW *fw,char *outputLine,lineInfo *li) {

    char temp;
    int i=0;
    int isEndFile=1;

    if (fw->fp==NULL)
        return FALSE;

    if ( li == NULL ){
        return FALSE;
    }

    if( ftell(fw->fp) == 0){
        li->lineNum = 1;
    }

    while (!feof(fw->fp)) {
        if (i==MAX_LENGTH_OF_LINE) { /* The line has exceeded the maximum limit */
            li->nowPos=ftell(fw->fp);
            return -1;
        }
        if ((temp=fgetc(fw->fp))!='\n') {
            outputLine[i++]=temp;
        } else {
            outputLine[i]='\0';
            li->nowPos=ftell(fw->fp);
            (li->lineNum)++;   /* equals '\n', encouter line end */
            isEndFile=0;
            break;
        }
    }
    if (isEndFile) {
        outputLine[i]='\0';
        return FALSE;
    }
    return TRUE;
}

BOOL
getKeyAndValue(const char *line,char *key,char *value) {
    int i;
    int mK,mV;
	int index=0;
    mK=mV=0;

    for (i=0; line[i]&&line[i]!='\n'&&line[i]!='\0'; i++) {
        if (((line[i]>='A')&&(line[i]<='Z'))||(line[i]>='a'&&line[i]<='z')||(line[i]>='0'&&line[i]<='9')||(line[i]=='_')||mK==1) {
            do {

                if (mK==0) {
                    key[index++]=line[i++];
                } else {
                    value[index++]=line[i++];
                }
            } while (((line[i]>='A'&&line[i]<='Z')||(line[i]>='a'&&line[i]<='z')||(line[i]>='0'&&line[i]<='9')||line[i]=='_'||mK==1)&&(line[i]!='\n'&&line[i]!='\0'));
            if (mK==0) {
                key[index]='\0';
            } else {
                value[index]='\0';
            }
            index=0;  /*Rest index to 0 when key is finished.*/
            if (key[0]!='\0')
                mK=1;
            if (value[0]!='\0')
                mV=1;
        }

    }
    if ( (mK==mV) && (1==mK) )
        return TRUE;
    else
        return FALSE;
}


/* skip_comments(file) : read past comment (if any)
 */
void
skipComments(FILE *file)
{
	int	ch;

	while (EOF != (ch = fgetc(file))) {
		/* ch is now the first character of a line.
		 */

		while (ch == ' ' || ch == '\t')
			ch = fgetc(file);

		if (ch == EOF)
			break;

		/* ch is now the first non-blank character of a line.
		 */
		if (ch != '\n' && ch != '#')
			break;

		/* ch must be a newline or comment as first non-blank
		 * character on a line.
		 */

		while (ch != '\n' && ch != EOF)
			ch = fgetc(file);

		/* ch is now the newline of a line which we're going to
		 * ignore.
		 */
	}
	if (ch != EOF)
		ungetc(ch, file);
}


/*
 * strdlb - delete leading blanks in string s and return new length
 *
 */
int
strdlb(char *s){
    const char *pTmp;
	char *x=s;
    ASSERT(s!=NULL);

	/*Stop at the first non-blank char*/
	while(*x==' ')
		x++;

	if(x==s)
		return strlen(s);
	else{
        pTmp=x;
		while(x!='\0')
			s=x;
			s++;
			x++;
		s='\0';
		return strlen(pTmp);
	}
}

/* strdtb(s) - delete trailing blanks in string 's' and return new length
 */
int
strdtb(char *s)
{
	char	*x = s;

	/* scan forward to the null
	 */
	while (*x)
		x++;

	/* scan backward to either the first character before the string,
	 * or the last non-blank in the string, whichever comes first.
	 */
	do	{x--;}
	while (x >= s && isspace(*x));

	/* one character beyond where we stopped above is where the null
	 * goes.
	 */
	*++x = '\0';

	/* the difference between the position of the null character and
	 * the position of the first character of the string is the length.
	 */
	return x - s;
}

uint64
str2flags(struct flag *tflags, char *sflags)
{
	long long flags = 0;
	unsigned int i;
	char *f;

	for (f = strtok(sflags, ","); f != NULL; f = strtok(NULL, ",")) {
		/* Support magic 'none' flag which just reset all flags. */
		if (strcmp(f, "none") == 0)
			return (0);
		for (i = 0; tflags[i].f_str != NULL; i++) {
			if (strcmp(tflags[i].f_str, f) == 0)
				break;
		}
		if (tflags[i].f_str == NULL) {
			fprintf(stderr, "unknown flag '%s'\n", f);
			exit(1);
		}
		flags |= tflags[i].f_flag;
	}
	return (flags);
}

char *
flags2str(struct flag *tflags, long long flags)
{
	static char sflags[1024];
	unsigned int i;

	sflags[0] = '\0';
	for (i = 0; tflags[i].f_str != NULL; i++) {
		if (flags & tflags[i].f_flag) {
			if (sflags[0] != '\0')
				strncat(sflags, ",", sizeof(sflags));
			strncat(sflags, tflags[i].f_str, sizeof(sflags));
		}
	}
	if (sflags[0] == '\0')
		strncpy(sflags, "none", sizeof(sflags));
	return (sflags);

}

uint64 
splitstring(const char *str, const char c, char *arr[], int n){
    char *p1, *p2;
    int i = 0;
    p1 = p2 = (char *) str;
    for (; *p1; p1++) {
        if (*p1 == c) {
            *p1 = 0;
            if (i < n)
                arr[i++] = p2;
            p2 = p1+1;
        }
    }
    if (i < n)
        arr[i++] = p2;
    return i;
}

